package cn.darkhorse.mesadmin.task;

import com.baomidou.mybatisplus.extension.toolkit.SqlRunner;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

@Component("copyMqttDataTask")
public class CopyMqttDataTask {
    private static final Logger log = LoggerFactory.getLogger(CopyMqttDataTask.class);
    public static final String COPY_DATA = "CopyData";
    @Resource
    private RedisTemplate redisTemplate;

//    @Scheduled(cron = "0/20 * * * * *")
    @DataSource(DataSourceType.SLAVE)
    public void getData() {
        Object copyMaxId = redisTemplate.opsForValue().get("CopyMaxId");
        Long maxId = null;
        if (copyMaxId != null) {
            maxId = Long.parseLong(copyMaxId.toString());
        }

        List<Map<String, Object>> maps = SqlRunner.db().selectList(getSql(maxId));
        if (maps.size() != 0) {
            redisTemplate.opsForList().rightPushAll(COPY_DATA, maps);
            Map<String, Object> map = maps.get(maps.size() - 1);
            maxId = Long.parseLong(map.get("id").toString());
            redisTemplate.opsForValue().set("CopyMaxId",maxId);
        }
    }

    @NotNull
    private String getSql(Long maxId) {
        if (maxId == null) {
            return "select top 100 * from mqtt_data order by id desc";
        }else {
            return String.format("select top 10000 * from mqtt_data where id > %s order by id desc", maxId);
        }
    }

//    @Scheduled(cron = "0/10 * * * * *")
    @DataSource(DataSourceType.MASTER)
    public void writeData() {
        Long length = redisTemplate.opsForList().size(COPY_DATA);
        for (int i = 0; i <length; i++) {
            Map<String, Object> map = (Map<String, Object>) redisTemplate.opsForList().leftPop(COPY_DATA);
            doWriteData(map);
        }
    }


    @DataSource(DataSourceType.MASTER)
    public void doWriteData(Map<String, Object> map) {
        if (map == null ) {
            return;
        }
        String sql = "INSERT INTO mqtt_data (\n" +
                "\t`client_id`,\n" +
                "\t`topic`,\n" +
                "\t`DATA`,\n" +
                "\t`qos`,\n" +
                "\t`add_date`,\n" +
                "\t`device_id`,\n" +
                "\t`client_date`,\n" +
                "\t`flag`,\n" +
                "`data_type`)\n" +
                "VALUES\n" +
                "\t( \n" +
                "\t{0}, \n" +
                "\t{1}, \n" +
                "\t{2}, \n" +
                "\t{3}, \n" +
                "\t{4}, \n" +
                "\t{5}, \n" +
                "\t{6}, \n" +
                "\t0, \n" +
                "\t{7} )";

        SqlRunner.db().insert(sql
                ,map.get("client_id").toString()
                ,map.get("topic").toString()
                ,map.get("data").toString()
                ,map.get("qos").toString()
                ,convert(map.get("add_date").toString())
                ,map.get("device_id").toString()
                ,convert(map.get("client_date").toString())
                ,map.get("data_type").toString()
        );
    }

    private String convert(String time) {
        long timestamp =  Long.parseLong(time);
        Instant instant = Instant.ofEpochMilli(timestamp);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(ZoneId.systemDefault());
        String formattedDate = dtf.format(instant);
        return formattedDate;
    }


}
